package DAO;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import model.User;
import database.DBManager;

public class UserDao {

	private String sqlread   	   = "SELECT * FROM user";
	private String sqlGetU   	   = "SELECT * FROM user WHERE userID = ?";
	private String sqlGetN   	   = "SELECT * FROM user WHERE username = ?";
	private String sqlLogin		   = "SELECT * FROM user WHERE username = ? AND password = ?";
	private String sqlCreate   	   = "INSERT INTO user(username, password, rollID) VALUES(?, ?, ?)";
	private String sqlDelete   	   = "DELETE FROM user WHERE userID = ?";
	
	private Connection        con      = null;
	private PreparedStatement psRead   = null;
	private PreparedStatement psGetU   = null;
	private PreparedStatement psGetN   = null;
	private PreparedStatement psLogin  = null;
	private PreparedStatement psCreate = null;
	private PreparedStatement psDelete = null;

	public UserDao(DBManager myDb){
		setStatements(myDb);
	}
	
	private void setStatements(DBManager myDb){
		con = myDb.getConnection();
		try{
			this.psRead   = con.prepareStatement(sqlread);
			this.psGetU   = con.prepareStatement(sqlGetU);
			this.psGetN   = con.prepareStatement(sqlGetN);
			this.psLogin  = con.prepareStatement(sqlLogin);
			this.psCreate = con.prepareStatement(sqlCreate);
			this.psDelete = con.prepareStatement(sqlDelete);
		} catch(SQLException se) {
			se.printStackTrace();
		}
	}
	
	public ArrayList<User> getUsers(){
		ArrayList<User> users = new ArrayList<User>();
		try{
			ResultSet rs = psRead.executeQuery();
			while (rs.next()) {
				int userID = rs.getInt(1);
				String username = rs.getString(2);
				String password = rs.getString(3);
				int rolID = rs.getInt(4);
				
				User user = new User(userID, username, password, rolID);
				users.add(user);
			}
			rs.close() ;
		} catch(SQLException se) {
			se.printStackTrace();
		}
		return users;
	}	
	
	public boolean uniqueUsername(String gebruikersnaam){
		boolean unique = true;
		try{
			psGetN.clearParameters() ;
			psGetN.setString(1, gebruikersnaam);
			ResultSet rs = psGetN.executeQuery();
			while (rs.next()) {
				unique = false;
			}
			rs.close() ;
		} catch(SQLException se) {
			se.printStackTrace();
		}
		return unique;
	}
	
	public User getUserByID(int getUserID){
		User user = null;
		try{
			psGetU.clearParameters() ;
			psGetU.setInt(1, getUserID);
			ResultSet rs = psGetU.executeQuery();
			while (rs.next()) {
				int userID = rs.getInt(1);
				String username = rs.getString(2);
				String password = rs.getString(3);
				int rolID = rs.getInt(4);
				
				user = new User(userID, username, password, rolID);
			}
			rs.close() ;
		} catch(SQLException se) {
			se.printStackTrace();
		}
		return user;
	}
	
	public User getUserByUsername(String getUsername){
		User user = null;
		try{
			psGetN.clearParameters() ;
			psGetN.setString(1, getUsername);
			ResultSet rs = psGetN.executeQuery();
			while (rs.next()) {
				int userID = rs.getInt(1);
				String username = rs.getString(2);
				String password = rs.getString(3);
				int rolID = rs.getInt(4);
				
				user = new User(userID, username, password, rolID);
			}
			rs.close() ;
		} catch(SQLException se) {
			se.printStackTrace();
		}
		return user;
	}
	
	private String hashPassword( String password ) {
		String hashword = null;
		String saltedPassword = ":5?#~}&D" + password + "35edfd3$es";
		try {
			MessageDigest md5 = MessageDigest.getInstance( "MD5" );
			md5.update( saltedPassword.getBytes() );
			BigInteger hash = new BigInteger( 1, md5.digest() );
			hashword = hash.toString( 16 );
		} catch( NoSuchAlgorithmException e ) {
			e.printStackTrace();
		}
		return hashword;
	}
	
	public User userLogin( String username, String password ) {
		User user = null;
		String hashedPassword = hashPassword( password );
		try {
			psLogin.clearParameters();
			psLogin.setString( 1, username );
			psLogin.setString( 2, hashedPassword ); 
			ResultSet rs = psLogin.executeQuery();
			while( rs.next() ) {
				int userID = rs.getInt(1);
				int rolID = rs.getInt(4);
				user = new User(userID, username, password, rolID);
			}
			rs.close();
		} catch( SQLException se ) {
			se.printStackTrace();
		}
		return user;
	}
	
	public boolean createKlant(String username, String password, int rollID) {
		boolean succeeded = false;
		try {
			psCreate.clearParameters();
			psCreate.setString( 1, username );
			psCreate.setString( 2, hashPassword(password) );
			psCreate.setInt( 3, rollID );
			if( psCreate.executeUpdate() != 0 ) {
				succeeded = true;
			}
		} catch( SQLException se ) {
			se.printStackTrace();
		}
		return succeeded;
	}
	
	public boolean deleteUser(int userID) {
		boolean succeeded = false;
		try {
			psDelete.clearParameters();
			psDelete.setInt( 1, userID );
			if( psDelete.executeUpdate() != 0 ) {
				succeeded = true;
			}
		} catch( SQLException se ) {
			se.printStackTrace();
		}
		return succeeded;
	}
	
}
